package chatsystem;

import java.net.InetAddress;
import java.net.UnknownHostException;

/**
 *
 * @author Diane
 */
public class InetAddressUtil {
  /**
   * Donne le masque réseau associée à la classe d'une adresse
   * Internet stockée dans quatre cases d'un tableau d'octets.
   * @param address tableau d'octets contenant l'adresse Internet.
   * @param offset index du premier octet de l'adresse dans le tableau.
   * @return l'objet adresse Internet contenant le masque réseau.
   * @exception UnknownHostException si l'adresse est de classe
   * D ou E.
   */
  public static InetAddress getMask(byte[] address, int offset)
    throws UnknownHostException {
    byte[] mask = new byte[4];
    if(address[offset]==0){
      throw new UnknownHostException();
    }
    mask[0]=(byte)255;
    if((address[offset]&  0x80000000)==0) {
      // Adresse de classe A
      return byteToInetAddress(mask,0);
    }
    mask[1]=(byte)255;
    if((address[offset]& 0x40)==0) {
      // Adresse de classe B
      return byteToInetAddress(mask,0);
    }
    if((address[offset] & 0x20)==0){
      // Adresse de classe C
      mask[2]=(byte)255;
      return byteToInetAddress(mask,0);
    }
    // Adresse de classe D ou E
    throw new UnknownHostException();
  }
  /**
   * Donne l'adresse de broadcast IP associée à la classe
   * d'une adresse Internet stockée dans quatre cases
   * d'un tableau d'octets.
   * @param address tableau d'octets contenant l'adresse Internet.
   * @param offset index du premier octet de l'adresse dans le tableau.
   * @return l'objet adresse Internet contenant l'adresse de
   * broadcast.
   * @exception UnknownHostException si l'adresse est de classe
   * D ou E.
   */
  public static InetAddress getBroadcast(byte[] address, int offset)
    throws UnknownHostException {
    byte[] broadcast = new byte[4];
    broadcast[0]=address[offset];
    if((address[offset]&  0x80000000)==0) {
      // Adresse de classe A
      broadcast[1]=(byte)255;
      broadcast[2]=(byte)255;
      broadcast[3]=(byte)255;
      return byteToInetAddress(broadcast,0);
    }
    broadcast[1]=address[offset+1];
    if((address[offset]& 0x40)==0) {
      // Adresse de classe B
      broadcast[2]=(byte)255;
      broadcast[3]=(byte)255;
      return byteToInetAddress(broadcast,0);
    }
    if((address[offset] & 0x20)==0){
      // Adresse de classe C
      broadcast[2]=address[offset+2];
      broadcast[3]=(byte)255;
      return byteToInetAddress(broadcast,0);
    }
    // Adresse de classe D ou E
    throw new UnknownHostException();
  }

  /**
   * Construit l'adresse de broadcast IP déduite
   * de l'adresse Internet locale.
   * @return l'objet adresse Internet de broadcast.
   */
  public static InetAddress getLocalBroadcast()
    throws UnknownHostException{
    byte[] localAddress = InetAddress.getLocalHost().getAddress();
    return getBroadcast(localAddress,0);
  }

  /**
   * Transforme une adresse Internet stockée dans quatre
   * cases d'un tableau de byte en un objet InetAddress.
   * @param address tableau d'octets contenant l'adresse Internet.
   * @param offset index du premier octet de l'adresse dans le tableau.
   * @return l'objet adresse Internet.
   */
  public static InetAddress byteToInetAddress(byte[] address, int offset)
    throws UnknownHostException{
    StringBuffer buffer = new StringBuffer(15);
    int tmp;
    for(int i=0;i<4;i++){
      // Récupère la valeur non signée de l'octet
      tmp = address[offset+i] & 0x7F;
      // Récupère le bit de signe qui, à cause de la
      // promotion entière de l'octet, se trouve dans
      //l'octet de poids fort d'un entier
      if((address[offset+i]&80000000)!=0)
	tmp = tmp | 0x80;

      buffer.append(tmp);
      if(i!=3)
	buffer.append('.');
    }
    return InetAddress.getByName(buffer.toString());
  }
}